# coding=UTF-8
from PIL import Image, ImageDraw
import os
import numpy as np
from pylab import *
import cv2 as cv
import cv2
import plot as pt

#批量细化图片
def batchthin(images):
    ret=[]
    for i in range(len(images)):
        temp=thin(images[i])
      #  pt.yulan(temp)
        ret.append(temp)
    return ret;


def resize(srcimg,savepath):
    height=8
    width=8

    im = srcimg
    (x, y) = im.size
    try:
        if(x>y):
            new_width=int(float(x/y)*width)
            new_height=height;
            out = im.resize((new_width, new_height), Image.ANTIALIAS)
            region=(int(new_width/2-width/2),0,int(new_width/2-width/2+width),height)
            out=out.crop(region)
        else:
            new_height=int(y/x*height)
            new_width=width
            out = im.resize((new_width, new_height), Image.ANTIALIAS)
            region=(0,int(new_height/2-height/2),width,int(new_height/2-height/2+height))
            out = out.crop(region)
        out.save(savepath)
    except:
        pass
        return




#二值图像快速细化
def thin(image) :
    height=image.shape[0]
    width=image.shape[1]
    laynum=np.zeros((height, width), dtype = 'int32')
    for y in range(height):
        for x in range(width):
            if(x==0 or y==0 or x==width-1 or y==height-1):
                image[y][x]=1;



    #第一层细化(从上到下，从左到右)
    for y in range(1,height-1):
        for x in range(1,width-1):
            if(image[y][x]==0):
                f0=laynum[y][x-1]
                f1=laynum[y-1][x-1]
                f2=laynum[y-1][x]
                f3=laynum[y-1][x+1]
                laynum[y][x]=min(f0,f1,f2,f3)+1;
            else:
                laynum[y][x]=0;
    #第二层细化(从下道上，从右向左)
    for y in range(height-2,0,-1):
        for x in range(width-2,0,-1):
            if(image[y][x]==0):
                f0=laynum[y][x+1]
                f1=laynum[y+1][x+1]
                f2=laynum[y+1][x]
                f3=laynum[y+1][x-1]
                laynum[y][x]=min(f0,f1,f2,f3)+1;
            else:
                laynum[y][x]=0;
    #细化过程(从上到下，从做到右，周边8个点，如果当前的层数不是最大，即可删除该点)
    for y in range(1,height-1):
        for x in range(1,width-1):
            if(image[y][x]==0):
                f=laynum[y][x]
                f1=laynum[y-1][x-1]
                f2=laynum[y-1][x]
                f3=laynum[y-1][x+1]
                f4=laynum[y][x-1]
                f5=laynum[y][x+1]
                f6=laynum[y+1][x-1]
                f7=laynum[y+1][x]
                f8=laynum[y+1][x+1]
                vtemp=max(f1,f2,f3,f4,f5,f6,f7,f8)
                if(f<vtemp):
                    image[y][x]=1

    return image;



















def resize(image, towidth, toheight):
    destimg = np.empty((toheight, towidth), dtype='int32')
    srcheight = image.shape[0]
    srcwidth = image.shape[1]
    for y in range(toheight):
        for x in range(towidth):
           # print ("y= %s,x=%s" % (y,x))
            srcx = (float(x) * float(srcwidth)) / float(towidth)
            srcy = (float(y) * float(srcheight) / float(toheight))
            destimg[y][x] = interpol(image, srcx, srcy)
    return destimg;


def batchresize(images, towidth, toheight):
    ret = [];
    size = (towidth, toheight)
    for i in range(len(images)):
        image = images[i];
        temp = resize(image, towidth, toheight)
        pt.yulan(temp)
        ret.append(temp)
    return ret;


# 图片二值化
def binarrimage(image, shlodv):
    row = image.shape[1];
    col = image.shape[2];
    ret = np.empty(row * col)
    for i in range(row):
        for j in range(col):
            v = ret[i * col + j]
            if (v < shlodv):
                ret[i * col + j] = 0
            else:
                ret[i * col + j] = 1
    return ret;


def interpol(image, x, y):
    toy = int(y)
    tox = int(x)
    v = image[toy][tox]
    return v


# 传入元素 RGB值(二次线性插值法，放大图片)
# image  pixtype : 0,1,2三种类型
def interpolation(image, x, y):
    width = image.shape[0]
    height = image.shape[1]
    j1, j2 = 0;
    f1, f2, f3, f4 = 0;
    f12, f34 = 0
    EXP = 0;
    i1 = int(x);
    i2 = i1 + 1;
    j1 = int(y)
    j2 = j1 + 1
    r, g, b = 0;
    if ((x < 0) or (x > width - 1) or y < 0 or y > -1):
        return 1
    else:
        if (abs(x - width + 1) <= EXP):
            if (abs(y - height + 1) <= EXP):
                f1 = int(image[j1][i1])
                return f1
            else:
                f1 = int(image[j1][i1]);
                f3 = int(image[j1][i2]);
                return int(f1 + (y - j1) * (f3 - f1))


        elif (abs(y - height + 1) <= EXP):
            f1 = int(image[j1][i1])
            f3 = int(image[j2][i1])
            return int(f1 + (x - i1) * (f3 - f1))
        else:
            f1 = int(image[j1][i1])
            f2 = int(image[j2][i1])
            f3 = int(image[j1][i2])
            f4 = int(image[j2][i2])
            f12 = int(f1 + (x - i1) * (f2 - f1));
            f34 = int(f3 + (x - i1) * (f4 - f3));
            v = int(f12 + (y - j1) * (f34 - f12))
            return v;


# 灰度图重设图片大小(缩小，放大)
def reshape(grayimage, destwidth, destheight):
    srcheight = grayimage.shape[0];
    srcwidth = grayimage.shape[1];
    destimg = np.empty((1, destwidth, destheight), dtype='int32')
    for x in range(srcwidth):
        for y in range(srcheight):
            srcx = (float(x) * float(srcwidth)) / float(destwidth)
            srcy = (float(y) * float(srcheight) / float(destheight))
            destimg[x][y] = interpolation(grayimage, srcx, srcy)
    return destimg;


def cutimage(image, hpixcount, vpixcount):
    # 跳跃法水平切割
    #horline = horizontalCiseLine(image, hpixcount)
    horline=(0,image.shape[0]-1);
    # 阈值法获取垂直切割点
    verline = vericalThresholdLine(image, vpixcount)
    # 图片切割
    #pt.paintOutLineOfChr(image, horline, verline)
    ret = corpImageByCiseLine(image, horline, verline)

    return ret;


# 阈值切割法(水平切割线)
def horizontalThresholdLine(image, hminsize):
    height = image.shape[0]
    width = image.shape[1]
    vpos = np.zeros((height))
    hbegin = 0;
    hend = 0;
    for y in range(height):
        for i in range(width):
            if (image[y][i] == 0):
                vpos[y] = vpos[y] + 1;
    for i in range(len(vpos)):
        if (hbegin == 0 and vpos[i] > hminsize and vpos[i + 1] > hminsize and vpos[i + 2] > hminsize):
            hbegin = i;
        if (hbegin != 0 and vpos[i] < hminsize and vpos[i + 1] < hminsize and vpos[i + 2] < hminsize):
            hend = i;
            break;
    return (hbegin, hend)


# 阈值切割法(垂直切割线)
def vericalThresholdLine(image, vminsize):
    height = image.shape[0]
    width = image.shape[1]
    vpos = np.zeros((width))
    vbegin = 0
    vend = 0
    ret = []
    for x in range(width):
        for y in range(height):
            if (image[y][x] == 1):
                vpos[x] = vpos[x] + 1;
    for i in range(len(vpos)):
        if (i > (len(vpos) - 3)):
            break;
        if (vbegin == 0 and vpos[i] > vminsize and vpos[i + 1] > vminsize and vpos[i + 2] > vminsize):
            vbegin = i;
        if (vbegin != 0 and vpos[i] < vminsize and vpos[i + 1] < vminsize and vpos[i + 2] < vminsize):
            vend = i;
            if ((vend - vbegin) > (width / 13)):
                ret.append((vbegin, vend))
            vbegin = 0
            vend = 0
    return ret;


# 跳跃点文字切割法（水平切割线）
def horizontalCiseLine(pixs, hminsize):
    height = pixs.shape[0]
    width = pixs.shape[1]
    # 水平跳跃点
    hpos = horizontalCise(pixs)
    hbegin = 0
    hend = 0
    for i in range(3, len(hpos)):
        if i > width - 3:
            break;
        if (hbegin == 0 and hpos[i] > hminsize and hpos[i + 1] > hminsize and hpos[i + 2] > hminsize):
            hbegin = i
        if (hbegin != 0 and hpos[i] < hminsize and hpos[i + 1] < hminsize and hpos[i + 2] < hminsize):
            hend = i
            break;
    return (hbegin, hend)


# 跳跃点文字切割法(垂直切割线)
def vericalCiseLine(image, horline, vminsize):
    # 垂直跳跃点
    vpos = verticalCise(image)
    arr = []
    hbegin = horline(0)
    hend = horline(1)
    vbegin = 0
    vend = 0
    # pt.paintRectange(pixs, (0, hbegin), (width, hend))
    if (hbegin == 0 or hend == 0): return;
    for j in range(vpos.length):
        if (vbegin == 0 and vpos[j] > vminsize and vpos[j + 1] > vminsize and vpos[j + 2] > vminsize):
            vbegin = vpos[j]
        if (vbegin != 0 and vpos[j] < vminsize and vpos[j + 1] < vminsize and vpos[j + 2] < vminsize):
            vend = vpos[j]
            # 获取截取范围点
            arr.append((vbegin, vend));
            vbegin = 0;
            vend = 0;


# 根据水平切割线和垂直切割线进行图片切割
def corpImageByCiseLine(image, horline, verline):
    ret = []
    y0 = horline[0]
    y1 = horline[1]
    clen = len(verline)
    for i in range(clen):
        point = (verline[i][0], y0, verline[i][1], y1)
        v = corpImage(image, point)
        #pt.yulan(v)
        ret.append(v)
    return ret;


# 根据左上，右下角坐标，进行图片剪裁
def corpImage(pixs, point):
    height = pixs.shape[0]
    width = pixs.shape[1]
    x1 = point[0]
    y1 = point[1]
    x2 = point[2]
    y2 = point[3]
    w = x2 - x1 + 1
    h = y2 - y1 + 1
    ret = np.empty([h, w], dtype='int32')
    for i in range(w):
        for j in range(h):
            ret[j][i] = pixs[y1 + j][x1 + i]
    return ret;


# 获取图片水平跳跃点(灰度图)

def horizontalCise(image):
    height = image.shape[0]
    width = image.shape[1]
    vpos = np.zeros((height))
    for y in range(height):
        for x in range(1, width - 1):
            if (image[y][x] != image[y][x - 1]):
                vpos[y] = vpos[y] + 1;
    x = np.arange(height)
    # pt.paintHorBar(x, vpos)
    return vpos;


# 获取垂直跳跃点

def verticalCise(image):
    height = image.shape[0]
    width = image.shape[1]
    vpos = np.zeros((width))
    for x in range(width):
        for y in range(1, height - 1):
            if (image[y + 1][x] != image[y][x]):
                vpos[x] = vpos[x] + 1;
    x = np.arange(width)
    pt.paintVerBar(x, vpos)
    return vpos;


# 图片识别
def nocarregn(filepath):
    im = Image.open(filepath);
    width = im.shape[1];
    # 图片灰度化
    im = im.convert('L');
    # 图片二值化，并返回图片数组
    imarray = binarrimage(im, 170);


# 计算截取后图片的白像素斜率
def imslope(nuim):
    vpos = {};
    width = nuim.shape[1]
    height = nuim.shape[2]
    for i in range(width):
        for j in range(height):
            if (nuim[i][j] == 0):
                vpos.appand(i / j)
    return vpos;


# 降噪元素替换(灰度图)(每一个像素点)
def getNociePixel(image, x, y, N):
    L = image[y][x]
    nearDots = 0
    if L == (image[y - 1][x - 1]):
        nearDots += 1
    if L == (image[y][x - 1]):
        nearDots += 1
    if L == (image[y + 1][x - 1]):
        nearDots += 1
    if L == (image[y - 1][x]):
        nearDots += 1
    if L == (image[y + 1][x]):
        nearDots += 1
    if L == (image[y - 1][x + 1]):
        nearDots += 1
    if L == (image[y][x + 1]):
        nearDots += 1
    if L == (image[y + 1][x + 1]):
        nearDots += 1

    if nearDots < N:
        return 0 if L == 1 else 1
    else:
        return None


# image(numpy数组)
# 降噪率  0<N<8
def clearNoise(image, N):
    height = image.shape[0]
    width = image.shape[1]
    for y in xrange(1, height - 1):
        for x in xrange(1, width - 1):
            color = getNociePixel(image, x, y, N)
            if color != None:
                image[y][x] = color
    return image;


# 计算 2张图片文字斜率的余弦角度
def cosOfIms(im1, im2):
    width1 = im1.shape[1]
    width2 = im2.shape[2]
    x = 1;
    y = 1;
    x2 = 0;
    y2 = 0;
    for i in range(width1):
        x = x * im1[i]
        x2 = x2 + im1[i] * im1[i]
    for j in range(width2):
        y = y * im2[j]
        y2 = y2 + im2[j] * im2[j]
    cos = (x + y) / (x2 + y2)
    return cos;
